using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace OpenComposite.EII.RepositoryUIs
{
    public partial class FormSelectAPIMethods : Form
    {
        public FormSelectAPIMethods(Assembly api)
        {
            InitializeComponent();
            _apiAssembly = api;
            loadTypes();
            DialogResult = DialogResult.Cancel;
        }

        private Assembly _apiAssembly;
        private List<MethodInfo> _methods;

        public List<MethodInfo> SelectedMethods
        {
            get
            {
                fetchMethods();
                return _methods;
            }
        }

        #region Methods
        private void loadTypes()
        {
            dgvTypes.Rows.Clear();
            foreach (Type type in _apiAssembly.GetTypes()) {
                dgvTypes.Rows.Add(new object[]{type.FullName});
            }
        }
        private void loadMethods()
        {
            dgvMethods.Rows.Clear();
            Type type = _apiAssembly.GetType((string)dgvTypes.SelectedRows[0].Cells["colTypeName"].Value);
            foreach (MethodInfo meth in type.GetMethods()) {
                dgvMethods.Rows.Add();
                DataGridViewRow dgvRow = dgvMethods.Rows[dgvMethods.Rows.GetLastRow(DataGridViewElementStates.None)];
                dgvRow.Tag = meth;

                dgvRow.Cells["colMethName"].Value = meth.Name;
                dgvRow.Cells["colMethReturn"].Value = meth.ReturnType.Name;
                dgvRow.Cells["colMethParam"].Value = generateParameterList(meth);
            }
        }

        private string generateParameterList(MethodInfo method)
        {
            StringBuilder retString = new StringBuilder();
            foreach (ParameterInfo param in method.GetParameters()) {
                retString.Append(param.ParameterType.Name).Append(";"); 
            }
            if (retString.Length > 0)
                retString.Remove(retString.Length - 1, 1);
            return retString.ToString();
        }
        private void fetchMethods()
        {
            _methods = new List<MethodInfo>();
            dgvMethods.CommitEdit(DataGridViewDataErrorContexts.Commit);
            foreach (DataGridViewRow row in dgvMethods.Rows) {
                string s = (string)row.Cells[1].Value;
                if (row.Cells[0].Value != null && (bool)row.Cells[0].Value == true) {
                    _methods.Add((MethodInfo)row.Tag);
                }
            }
        }
        #endregion

        #region Events
        private void tsbtnOK_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
            this.Close();
        }

        private void tsbtnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            this.Close();
        } 

        private void dgvTypes_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvTypes.SelectedRows.Count > 0)
                loadMethods();
        }
        #endregion

        private void dgvMethods_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            StringBuilder msg = new StringBuilder();
            msg.Append("Column: ").AppendLine(e.ColumnIndex.ToString());
            msg.Append("Context: ").AppendLine(e.Context.ToString());
            msg.Append("Exception: ").AppendLine(e.Exception.Message);
            msg.Append("Row: ").AppendLine(e.RowIndex.ToString());
            MessageBox.Show(msg.ToString(), "Select Methods");
        }

        private void dgvTypes_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            StringBuilder msg = new StringBuilder();
            msg.Append("Column: ").AppendLine(e.ColumnIndex.ToString());
            msg.Append("Context: ").AppendLine(e.Context.ToString());
            msg.Append("Exception: ").AppendLine(e.Exception.Message);
            msg.Append("Row: ").AppendLine(e.RowIndex.ToString());
            MessageBox.Show(msg.ToString(), "Select Types");
        }

        private void dgvMethods_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if(e.ColumnIndex == colMethChecked.Index)
            {
                if (dgvMethods["colMethChecked", e.RowIndex].Value != null) {
                    dgvMethods["colMethChecked", e.RowIndex].Value = !(bool)dgvMethods["colMethChecked", e.RowIndex].Value;
                } else {
                    dgvMethods["colMethChecked", e.RowIndex].Value = true;
                }
            }
        }
    }
}